<html>
    <head>
        <title>添加菜单项</title>
    </head>
    <body>
        <script>
             /*
                         一、添加菜单项


                                  1、菜单贡献者  IMenuContributor

                                                    为了添加菜单项（或操作现有项），您需要创建一个实现 "IMenuContributor" 接口 的类。

                                                    (应用程序启动模板已经包含IMenuContributor的实现。因此，您可以在该类中添加项目，而不是创建新项目。)

                                                    eg: 添加带有客户和订单子菜单项的CRM菜单项

                                                            using System.Threading.Tasks;
                                                            using MyProject.Localization;
                                                            using Volo.Abp.UI.Navigation;

                                                            namespace MyProject.Web.Menus
                                                            {
                                                                public class MyProjectMenuContributor : IMenuContributor  // 创建菜单贡献者类
                                                                {
                                                                    public async Task ConfigureMenuAsync(MenuConfigurationContext context)
                                                                    {
                                                                        if (context.Menu.Name == StandardMenus.Main)
                                                                        {
                                                                            await ConfigureMainMenuAsync(context);
                                                                        }
                                                                    }

                                                                    //  没当渲染菜单时，ABP都会调用此方法。
                                                                    private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
                                                                    {
                                                                        var l = context.GetLocalizer<MyProjectResource>(); // 获取本地化资源对象

                                                                        context.Menu.AddItem(  // 添加菜单项
                                                                            new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"]) // 添加应用程序菜单
                                                                                .AddItem(new ApplicationMenuItem(
                                                                                    name: "MyProject.Crm.Customers",  // 菜单项名称
                                                                                    displayName: l["Menu:Customers"],  // 显示名称
                                                                                    url: "/crm/customers") // 页面路径
                                                                                ).AddItem(new ApplicationMenuItem(
                                                                                    name: "MyProject.Crm.Orders", 
                                                                                    displayName: l["Menu:Orders"],
                                                                                    url: "/crm/orders")
                                                                                )
                                                                        );
                                                                    }
                                                                }
                                                            }

                                                            此示例仅将项目添加到主菜单（StandardMenus.Main：请参阅下面的Standard Menus部分）。

                                                            它从context到本地化获取一个IStringLocalizer菜单项的显示名称。

                                                            将客户和订单添加为CRM菜单的子级。

                                   2、注册菜单贡献者

                                                  创建菜单贡献者后，需要将其添加到模块的ConfigureServices方法中的 "AbpNavigationOptions"：

                                                            Configure<AbpNavigationOptions>(options =>
                                                            {
                                                                options.MenuContributors.Add(new MyProjectMenuContributor());
                                                            });

                                                  此示例使用一些本地化键作为显示名称，这些名称应在本地化文件中定义：

                                                            "Menu:CRM": "CRM",
                                                            "Menu:Orders": "Orders",
                                                            "Menu:Customers": "Customers"

                                                    
                                                  当您运行应用程序时，您将看到添加到主菜单中的菜单项.

                                                  (菜单由当前UI主题呈现。因此，主菜单的外观可以根据您的主题完全不同。)


                                                  一些关于"菜单贡献程序"的一些注释：

                                                            ①、每当需要渲染菜单时，ABP都会调用ConfigureMenuAsync方法。

                                                            ②、每个菜单项都可以有子。因此，您可以添加具有无限深度的菜单项（但是，您的UI主题可能不支持无限深度）。

                                                            ③、通常只有叶子菜单项有url。当您单击父菜单时，其子菜单会打开或关闭，您不会导航父菜单项的url。

                                                            ④、如果菜单项没有子项并且没有定义url，那么它不会在UI上呈现。

                                                                        简化了对菜单项的授权：您只授权子项（请参阅下一节）。如果没有子项被授权，则父项会自动消失。



                                    3、菜单项属性   Menu Item Properties

                                                菜单项有更多选项（ApplicationMenuItem类的构造函数）。在这里，所有可用选项的列表：

                                                        ①、name（string，必需）：菜单项的唯一名称。

                                                        ②、displayName（string，必需）：显示菜单项的名称/文本。您可以本地化，如前所示。

                                                        ③、url（string）：菜单项的URL。

                                                        ④、icon（string）：一个图标名称。开箱即用支持免费的Font Awese图标类

                                                                            示例：fa fa-book。您可以使用任何CSS字体图标类，只要您在应用程序中包含必要的CSS文件。

                                                        ⑤、order（int）：菜单项的顺序。默认值为1000。除非您指定订单值，否则项目按添加顺序排序。

                                                        ⑥、customData（Dictionary<string, object>）：允许存储自定义对象的字典，您可以将其与菜单项关联并在呈现菜单项时使用它。

                                                        ⑦、target（string）：菜单项的目标。可以是null，（默认）、"_blank"、"_self"、"_parent"、"_top"或Web应用程序的框架名称。

                                                        ⑧、elementId（string）：可用于呈现具有特定超文本标记语言id属性的元素。

                                                        ⑨、cssClass（string）：菜单项的附加字符串类。

                                                        ⑩、groupName（string）：可用于对菜单项进行分组。


                                    4、授权  Authorization

                                                    如上所示，菜单贡献者动态地为菜单做出贡献.

                                                    因此，您可以执行任何自定义逻辑或从任何来源获取菜单项

                                                    一个用例是授权。您通常希望通过检查权限来添加菜单项。

                                                    eg: 检查当前用户是否有权限

                                                        if (await context.IsGrantedAsync("MyPermissionName")) // 授权检查
                                                        {
                                                            //...添加菜菜单项目
                                                        }

                                                    对于授权，您可以使用RequirePermissions扩展方法作为快捷方式。它也更高性能，ABP优化了所有项目的权限检查。

                                                    eg:  
                                                        context.Menu.AddItem(
                                                            new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"])
                                                                .AddItem(new ApplicationMenuItem(
                                                                        name: "MyProject.Crm.Customers",
                                                                        displayName: l["Menu:Customers"],
                                                                        url: "/crm/customers")
                                                                    .RequirePermissions("MyProject.Crm.Customers")
                                                                ).AddItem(new ApplicationMenuItem(
                                                                        name: "MyProject.Crm.Orders",
                                                                        displayName: l["Menu:Orders"],
                                                                        url: "/crm/orders")
                                                                    .RequirePermissions("MyProject.Crm.Orders")
                                                                )
                                                        );


                                                    备注： 您可以使用上下文。AuthorizationService直接访问IAuthorizationService。


                                    5、菜单贡献者类中解决依赖关系   Resolving Dependencies

                                                    context.ServiceProvider可用于解决任何服务依赖关系。

                                                    eg:  获取服务

                                                         var myService = context.ServiceProvider.GetRequiredService<IMyService>();
                                                         //...使用服务

                                                    你不要关系服务的释放和销毁，ABP会处理它。


                                    6、管员理菜单  The  Administrator Menu 
                                    
                                                    菜单菜单中有一个由ABP添加的特殊菜单项：管理菜单。

                                                    它通常由预构建的 "管理员应用程序模块" 使用：

                                                    如果要在管理菜单项下添加菜单项，可以使用context.Menu.GetAdministration()扩展方法：

                                                            context.Menu.GetAdministration().AddItem(...)


                                    7、操作现有菜单

                                                   ABP按模块依赖顺序执行菜单贡献者。    
                                                   
                                                   因此，您可以操作应用程序或模块（直接或间接）依赖的菜单项。

                                                   eg: 为身份模块添加的Users菜单项设置一个图标
                                                            
                                                          var userMenu = context.Menu.FindMenuItem(IdentityMenuNames.Users);
                                                          userMenu.Icon = "fa fa-users";    

                                                    (context.Menu使您能够访问先前菜单贡献者添加的所有菜单项。)


                                    8、菜单组   Menu Groups

                                                   您可以定义组并将菜单项与组相关联

                                                   eg：  

                                                            using System.Threading.Tasks;
                                                            using MyProject.Localization;
                                                            using Volo.Abp.UI.Navigation;

                                                            namespace MyProject.Web.Menus
                                                            {
                                                                public class MyProjectMenuContributor : IMenuContributor
                                                                {
                                                                    public async Task ConfigureMenuAsync(MenuConfigurationContext context)
                                                                    {
                                                                        if (context.Menu.Name == StandardMenus.Main)
                                                                        {
                                                                            await ConfigureMainMenuAsync(context);
                                                                        }
                                                                    }

                                                                    private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
                                                                    {
                                                                        var l = context.GetLocalizer<MyProjectResource>();

                                                                        context.Menu.AddGroup(
                                                                            new ApplicationMenuGroup(
                                                                                name: "Main",
                                                                                displayName: l["Main"]
                                                                            )
                                                                        )
                                                                        context.Menu.AddItem(
                                                                            new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"], groupName: "Main")  // 添加到菜单组
                                                                                .AddItem(new ApplicationMenuItem(
                                                                                    name: "MyProject.Crm.Customers", 
                                                                                    displayName: l["Menu:Customers"], 
                                                                                    url: "/crm/customers")
                                                                                ).AddItem(new ApplicationMenuItem(
                                                                                    name: "MyProject.Crm.Orders", 
                                                                                    displayName: l["Menu:Orders"],
                                                                                    url: "/crm/orders")
                                                                                )
                                                                        );      
                                                                    }
                                                                }
                                                            }

                                                            UI主题将决定是否渲染组，如果它决定渲染，它的渲染方式取决于主题。只有LeptonX主题实现了菜单组。

                    */
        </script>
    </body>
</html>